package com.fcat.base.smartapi.lib;

import java.math.BigInteger;

public class KeyChangeToken extends BaseToken{
    public String StrTokenKey2;

    //ORIGINAL LINE: public byte[] ByteTokens2 = new byte[9];
    public byte[] ByteTokens2 = new byte[9];

    //ORIGINAL LINE: public ushort TCRC2;
    public int TCRC2;

    //ORIGINAL LINE: public byte KexpNo;
    public byte KexpNo;

    //ORIGINAL LINE: public byte KRN;
    public byte KRN;

    //ORIGINAL LINE: public byte RO;
    public byte RO;

    //ORIGINAL LINE: public byte Res;
    public byte Res;

    //ORIGINAL LINE: public byte KType;
    public byte KType;

    //ORIGINAL LINE: public byte TI;
    public byte TI;

    //ORIGINAL LINE: public ulong NewKey;
//    public long NewKey;
    public BigInteger NewKey;

    KeyChangeToken() {
        super.SetWorkType(WorkType.STA);
        this.TClassNum = 2;
        this.TSubClassNum = 3;
    }

    KeyChangeToken(boolean mode) {
        super.SetWorkType(WorkType.STA);
        this.testMode = mode;
        this.TClassNum = 2;
        this.TSubClassNum = 3;
    }

    KeyChangeToken(String newkey, String oldkey) {
        super.SetWorkType(WorkType.STA);
        this.TClassNum = 2;
        this.TSubClassNum = 3;
        this.KexpNo = 0;
        this.KRN = 1;
        this.RO = 0;
        this.Res = 0;
        this.KType = 0;
        this.TI = 0;
        this.EToK2ByteTokens(newkey);
        this.StrTokenKey2 = this.MakeToken(this.ByteTokens, oldkey);
//        this.ByteTokens.CopyTo(this.ByteTokens2, 0);
        System.arraycopy(this.ByteTokens, 0, this.ByteTokens2, 0, this.ByteTokens.length);
        this.TCRC2 = this.TCRC;
        this.EToByteTokens();
        this.StrToken = this.MakeToken(this.ByteTokens, oldkey);
    }

    public KeyChangeToken(byte kt, byte krnumbr, byte expiry, byte tindex, byte rollover,
                          String newkey, String oldkey, boolean mode) {
        super.SetWorkType(WorkType.STA);
        this.testMode = mode;
        this.TClassNum = 2;
        this.TSubClassNum = 3;
        this.KexpNo = expiry;
        this.KRN = krnumbr;
        this.RO = rollover;
        this.Res = 0;
        this.KType = kt;
        this.TI = tindex;
        this.EToK2ByteTokens(newkey);
        this.StrTokenKey2 = this.MakeToken(this.ByteTokens, oldkey);
//        this.ByteTokens.CopyTo(this.ByteTokens2, 0);
        System.arraycopy(this.ByteTokens, 0, this.ByteTokens2, 0, this.ByteTokens.length);
        this.TCRC2 = this.TCRC;
        this.EToByteTokens();
        this.StrToken = this.MakeToken(this.ByteTokens, oldkey);
    }

    @Override
    protected void EToByteTokens() {
        this.ByteTokens[0] = this.TClassNum;
        //ORIGINAL LINE: this.ByteTokens[1] = (byte)(((int)this.TSubClassNum << 4) + (this.KexpNo >> 4 & 15));
        this.ByteTokens[1] = (byte)(((int)this.TSubClassNum << 4) + (this.KexpNo >> 4 & 15));
        //ORIGINAL LINE: this.ByteTokens[2] = (byte)(((int)this.KRN << 4) + ((int)this.RO << 3) + ((int)this.Res << 2) + (int)(this.KType & 3));
        this.ByteTokens[2] = (byte)(((int)this.KRN << 4) + ((int)this.RO << 3) + ((int)this.Res << 2) + (int)(this.KType & 3));
        //ORIGINAL LINE: this.ByteTokens[3] = (byte)(this.NewKey >> 56 & 255UL);

        this.ByteTokens[3] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 56 & 255);
        //ORIGINAL LINE: this.ByteTokens[4] = (byte)(this.NewKey >> 48 & 255UL);
        this.ByteTokens[4] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 48 & 255);
        //ORIGINAL LINE: this.ByteTokens[5] = (byte)(this.NewKey >> 40 & 255UL);
        this.ByteTokens[5] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 40 & 255);
        //ORIGINAL LINE: this.ByteTokens[6] = (byte)(this.NewKey >> 32 & 255UL);
        this.ByteTokens[6] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 32 & 255);
    }

    private  boolean EToK2ByteTokens(String newkey) {
        if (this.TI > 255)
        {
            this.xErr = 21;
            return false;
        }
        if (this.KexpNo > 255)
        {
            this.xErr = 22;
            return false;
        }
        if (this.KRN > 9)
        {
            this.xErr = 23;
            return false;
        }
        if (this.RO > 1)
        {
            this.xErr = 24;
            return false;
        }
        if (this.Res > 1)
        {
            this.xErr = 25;
            return false;
        }
        if (this.KType > 3)
        {
            this.xErr = 26;
            return false;
        }
        if (!this.TransferNewKey(newkey))
        {
            this.xErr = 1;
            return false;
        }
        this.ByteTokens[0] = this.TClassNum;
        //ORIGINAL LINE: this.ByteTokens[1] = (byte)(((int)(this.TSubClassNum + 1) << 4) + (int)(this.KexpNo & 15));
        this.ByteTokens[1] = (byte)(((int)(this.TSubClassNum + 1) << 4) + (int)(this.KexpNo & 15));
        //ORIGINAL LINE: this.ByteTokens[2] = (this.TI & byte.MaxValue);
        this.ByteTokens[2] = (byte) (this.TI & 0xFF);
        //ORIGINAL LINE: this.ByteTokens[3] = (byte)(this.NewKey >> 24 & 255UL);
        this.ByteTokens[3] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 24 & 255);
        //ORIGINAL LINE: this.ByteTokens[4] = (byte)(this.NewKey >> 16 & 255UL);
        this.ByteTokens[4] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 16 & 255);
        //ORIGINAL LINE: this.ByteTokens[5] = (byte)(this.NewKey >> 8 & 255UL);
        this.ByteTokens[5] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) >> 8 & 255);
        //ORIGINAL LINE: this.ByteTokens[6] = (byte)(this.NewKey & 255UL);
        this.ByteTokens[6] = (byte)((this.NewKey.longValue() & 0xFFFFFFFFFFFFFFFFL) & 255);
        return true;
    }

    private boolean TransferNewKey(String innewkey) {
        if (innewkey.length() < 8)
        {
            this.xErr = 1;
            return false;
        }
        //ORIGINAL LINE: this.NewKey = ulong.Parse(innewkey, NumberStyles.HexNumber);
        this.NewKey = new BigInteger(innewkey, 16);
        return true;
    }

    public String MakeToken(byte[] source, String inkey)
    {
        return super.EToken(source, inkey);
    }

//ORIGINAL LINE: internal void MakeToken(byte kt, byte krnumbr, byte expiry, byte tindex, byte rollover, string innewkey, string inoldkey)
    public void MakeToken(byte kt, byte krnumbr, byte expiry, byte tindex, byte rollover, String innewkey, String inoldkey)
    {
        this.xErr = -1;
        this.TClassNum = 2;
        this.TSubClassNum = 3;
        this.KexpNo = expiry;
        this.KRN = krnumbr;
        this.RO = rollover;
        this.Res = 0;
        this.KType = kt;
        this.TI = tindex;
        this.EToK2ByteTokens(innewkey);
        this.StrTokenKey2 = this.MakeToken(this.ByteTokens, inoldkey);
//        this.ByteTokens.CopyTo(this.ByteTokens2, 0);
        System.arraycopy(this.ByteTokens, 0, this.ByteTokens2, 0, this.ByteTokens.length);
        this.TCRC2 = this.TCRC;
        this.EToByteTokens();
        this.StrToken = this.MakeToken(this.ByteTokens, inoldkey);
    }


}
